home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-20 | 5.3 KB | 196 lines | [TEXT/ROSA] |
- ;;;
- ;;; PowerLisp 2.0
- ;;; Copyright © 1996 Roger Corman. All rights reserved.
- ;;;
- ;;;
- ;;; Common Lisp 'setf' macro.
- ;;;
-
- (in-package :common-lisp)
- (provide :setf)
-
- (export '( fboundp
- fdefinition
- fmakunbound
- print-unreadable-object
- setf
- defsetf))
-
- (defun setf-function-symbol (function-specifier)
- (if (consp function-specifier)
- (let ((print-name (format nil "~:@(~A~)" function-specifier)))
- (intern print-name
- (symbol-package (cadr function-specifier))))
- function-specifier))
-
- (defmacro setf (&rest forms)
- (let ((form-list nil))
- (do* ((f forms (cddr f))
- (place (car f) (car f))
- (value (cadr f) (cadr f)))
- ((null f))
- (if (null (cdr f)) (error "Odd number of arguments to setf: ~A" forms))
- (if (symbolp place)
- (setq form-list (cons `(setq ,place ,value) form-list))
- (let ((expansion-func (get (car place) 'cl::_setf_expansion_)))
- (if (symbolp expansion-func)
- (setq form-list (cons `(,expansion-func ,value ,@(cdr place)) form-list))
- (setq form-list (cons `(funcall ,expansion-func ,value ,@(cdr place)) form-list))))))
- (if (cdr form-list)
- `(progn ,@(nreverse form-list))
- (car form-list))))
-
- ;;
- ;; Common Lisp 'defun' macro.
- ;; This redefines the built-in special form.
- ;;
- (defmacro defun (name lambda-list &rest forms)
- (let ((doc-form nil)
- (lambda-form nil)
- (declarations nil)
- (setf-form nil))
-
- (if (and (consp name) (eq (car name) 'setf))
- (progn
- (unless (symbolp (cadr name)) (error "Invalid function name: ~A" name))
- (setq setf-form (cadr name))
- (setq name (setf-function-symbol name))))
-
- ;; look for declarations and doc string
- (do* ((f forms (cdr f)))
- ((null f) (setq forms f))
- (if (and (typep (car f) 'string) (null doc-form) (cdr f))
- (setq doc-form
- `((setf (documentation ',name 'function) ,(car f))))
- (if (and (consp (car f)) (eq (caar f) 'declare))
- (push (car f) declarations)
- (progn (setq forms f) (return)))))
-
- (setq lambda-form
- `(lambda ,lambda-list ,@(nreverse declarations)
- (block ,name ,@forms)))
-
- (if setf-form
- `(progn
- ,@doc-form
- (setf (symbol-function ',name) (function ,lambda-form))
- (setf (get ',setf-form 'cl::_setf_expansion_) ',name)
- ',name)
- `(progn
- ,@doc-form
- (setf (symbol-function ',name) (function ,lambda-form))
- ',name))))
-
- ;;
- ;; Common Lisp 'defmacro' macro.
- ;; This redefines the built-in special form.
- ;;
- (defmacro defmacro (name lambda-list &rest forms)
- (let ((doc-form nil)
- (lambda-form nil)
- (declarations nil))
-
- ;; look for declarations and doc string
- (do* ((f forms (cdr f)))
- ((null f) (setq forms f))
- (if (and (typep (car f) 'string) (null doc-form) (cdr f))
- (setq doc-form
- `((setf (documentation ',name 'macro) ,(car f))))
- (if (and (consp (car f)) (eq (caar f) 'declare))
- (push (car f) declarations)
- (progn (setq forms f) (return)))))
-
- (setq lambda-form
- `(lambda (form &optional env)
- (destructuring-bind ,lambda-list
- (cdr form)
- ,@(nreverse declarations)
- (block ,name ,@forms))))
- `(progn
- ,@doc-form
- (setf (macro-function ',name) (function ,lambda-form))
- ',name)))
-
- (defun apply-arg-rotate (f args)
- (apply f (car (last args)) (butlast args)))
-
- (defmacro defsetf (sym first &rest rest)
- (if (symbolp first)
- `(progn (cl::putprop ',sym 'cl::_setf_expansion_ ',first) ',sym)
- (let ((f `#'(lambda ,(append (car rest) first) ,@(cdr rest)))
- (args (gensym)))
- `(progn
- (setf (get ',sym 'cl::_setf_expansion_)
- #'(lambda (&rest ,args) (apply-arg-rotate ,f ,args)))
- ',sym))))
-
- (defun fboundp (function-specifier)
- (if (consp function-specifier)
- (%fboundp (get (cadr function-specifier) '_setf_expansion_))
- (%fboundp function-specifier)))
-
- (defun fdefinition (function-specifier)
- (if (consp function-specifier)
- (symbol-function (get (cadr function-specifier) 'cl::_setf_expansion_))
- (symbol-function function-specifier)))
-
- (defun (setf fdefinition) (value function-specifier)
- (if (consp function-specifier)
- (let* ((func (cadr function-specifier))
- (set-sym (get func 'cl::_setf_expansion_)))
- (unless set-sym
- (progn
- (setq set-sym (setf-function-symbol function-specifier))
- (setf (get func 'cl::_setf_expansion_) set-sym)))
- (setf (symbol-function set-sym) value))
- (setf (symbol-function function-specifier) value)))
-
- (defun fmakunbound (function-specifier)
- (if (consp function-specifier)
- (%fmakunbound (get (cadr function-specifier) 'cl::_setf_expansion_))
- (%fmakunbound function-specifier)))
-
- ;;; print-unreadable-object is the standard way in the new Common Lisp
- ;;; to generate #< > around objects that can't be read back in. The option
- ;;; (:identity t) causes the inclusion of a representation of the object's
- ;;; identity, typically some sort of machine-dependent storage address.
-
- (defmacro print-unreadable-object
- ((object stream &key type identity) &body body)
- `(let ((.stream. ,stream)
- (.object. ,object))
- (format .stream. "#<")
- ,(when type
- '(format .stream. "~S" (type-of .object.)))
- ,(when (and type (or body identity))
- '(format .stream. " "))
- ,@body
- ,(when (and identity body)
- '(format .stream. " "))
- ,(when identity
- '(format .stream. "#x~X" (pl::address .object.))
- )
- (format .stream. ">")
- nil))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-